package org.bookr.console.controller;

import org.bookr.engine.model.Group;
import org.bookr.engine.service.BookrService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

/**
 * @author Pawel Tomaszewski
 */
@Controller
public class GroupController {
    private BookrService bookrService;
    private Logger logger = LoggerFactory.getLogger(GroupController.class);

    @RequestMapping(value = "/group/create", method = RequestMethod.GET)
    public ModelAndView createGroupForm() {
        ModelAndView result = new ModelAndView("console.createGroup");
        result.addObject("status", "console.webapp.status.fillForm");
        result.addObject("group", new Group());
        result.addObject("allReaders", bookrService.listReaders());
        return result;
    }

    @RequestMapping(value = "/group/create", method = RequestMethod.POST)
    public ModelAndView processCreateGroupForm(@ModelAttribute Group group, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.createComment");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "name", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "description", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allReaders", bookrService.listReaders());
            logger.debug("There was some errors: " + bindingResult.getAllErrors());
        } else {
            Date now = new Date();
            group.setCreatedDate(now);
            group.setLastUpdateDate(now);
            String id = bookrService.updateGroup(group);
            results.addObject("status", "console.webapp.status.createSuccess");
            results.addObject("group", bookrService.loadGroup(id));
            results.setViewName("console.group");
        }
        return results;
    }

    @RequestMapping(value = "/group/{id}/edit", method = RequestMethod.GET)
    public ModelAndView editGroupForm(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.editGroup");
        results.addObject("status", "console.webapp.status.fillForm");
        results.addObject("group", bookrService.loadGroup(id));
        results.addObject("allReaders", bookrService.listReaders());
        return results;
    }

    @RequestMapping(value = "/group/{id}/edit", method = RequestMethod.POST)
    public ModelAndView processEditGroupForm(@PathVariable String id,
                                             @ModelAttribute Group group, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.editGroup");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "name", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "description", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allReaders", bookrService.listReaders());
            logger.debug("There was some errors: " + bindingResult.getAllErrors());
        } else {
            group.setLastUpdateDate(new Date());
            bookrService.updateGroup(group);
            results.addObject("status", "console.webapp.status.editSuccess");
            results.addObject("group", bookrService.loadGroup(id));
            results.setViewName("console.group");
        }
        return results;
    }

    @RequestMapping("/groups")
    public ModelAndView listGroups() {
        ModelAndView results = new ModelAndView("console.groups");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("groups", bookrService.listGroups());
        return results;
    }

    @RequestMapping("/group/{id}")
    public ModelAndView showGroup(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.group");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("group", bookrService.loadGroup(id));
        return results;
    }

    @RequestMapping("/group/{id}/remove")
    public ModelAndView removeGroup(@PathVariable String id) {
        ModelAndView results = new ModelAndView("redirect:/groups");
        bookrService.removeGroup(bookrService.loadGroup(id));
        return results;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(Set.class, "readers", new CustomCollectionEditor(Set.class) {
            @Override
            public Object convertElement(Object element) {
                if(element instanceof String)
                    return bookrService.loadReaderById((String) element);
                return null;
            }
        });
    }

    public BookrService getBookrService() {
        return bookrService;
    }

    public void setBookrService(BookrService bookrService) {
        this.bookrService = bookrService;
    }
}